package com.java.distributed.service.impl;

import com.java.distributed.beans.MySession;
import com.java.distributed.service.MySessionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Service
public class MySessionServiceImpl implements MySessionService {

    private static  final ThreadLocal<MySession> sessionCache = new InheritableThreadLocal<>();

    private static MySession getLocalSesison(){
        return sessionCache.get();
    }

    private static void setLocalSesison(MySession mySession){
        sessionCache.set(mySession);
    }

    @Value("${session.timeout}")
    private Long sessionTimeout;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * session key值前缀
     */
    private final static String SESSION_PRE = "session_";

    @Override
    public MySession getSession(HttpServletRequest request, HttpServletResponse response) {
        String mySessionId = null;
        Cookie[] cookies = request.getCookies();
        if (null != cookies){
            for (Cookie cookie : cookies) {
                if ("mysessionid".equals(cookie.getName())){
                    mySessionId =cookie.getValue();
                }
            }
        }
        MySession session = null;
        if (!StringUtils.isEmpty(mySessionId)) {

            session = getLocalSesison();
            if (session == null){
                session =  (MySession) this.redisTemplate.opsForValue().get(SESSION_PRE + mySessionId);
            }

        }
        if (null == session) {
            mySessionId  = UUID.randomUUID().toString();
            session = new MySession();
            session.setSessionId(mySessionId);
            Cookie cookie = new Cookie("mysessionid",mySessionId);
            /**
             * 防止js修改cookie
             * 防止XSS攻击
             */
            cookie.setHttpOnly(true);
            cookie.setPath("/");
            response.addCookie(cookie);
        }
        setLocalSesison(session);
        return session;
    }

    @Override
    public void setSession( MySession session) {
        this.redisTemplate.opsForValue().set(SESSION_PRE + session.getSessionId(), session, sessionTimeout.longValue(), TimeUnit.MINUTES);
    }
}
